#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include "protocol.h"


/// 最小的合法包长度（不含 data）// 一帧总开销：2(头) + 2(类型) + 2(长度) + dataLen + 2(校验)
#define MIN_PACKET_LEN  8

// 返回值：>=0 表示打包后的总字节数；<0 表示出错（比如缓冲区空间不足）
int build_packet(
    uint16_t msgType,
    const uint8_t *data,
    uint16_t dataLen,
    uint8_t *buf,
    size_t buf_size
) {
    
    if ((size_t)dataLen + MIN_PACKET_LEN > buf_size) {
        return -1; // 空间不足
    }

    size_t index = 0;

    // 1) 协议头
    buf[index++] = 0xFF;
    buf[index++] = 0xFF;

    // 2) 消息类型（大端）
    buf[index++] = (msgType >> 8) & 0xFF;
    buf[index++] =  msgType       & 0xFF;

    // 3) 数据长度（大端）
    buf[index++] = (dataLen >> 8) & 0xFF;
    buf[index++] =  dataLen       & 0xFF;

    // 4) 数据域
    memcpy(buf + index, data, dataLen);
    index += dataLen;

    // 5) 校验码：累加 data 中所有字节
    uint16_t checkcode = 0;
    for (uint16_t i = 0; i < dataLen; ++i) {
        checkcode += data[i];
    }
    buf[index++] = (checkcode >> 8) & 0xFF;
    buf[index++] =  checkcode       & 0xFF;

    return (int)index;
}



int parse_packet(
    uint16_t *msgType,
    uint8_t  *data,
    uint16_t *dataLen,
    const uint8_t *buf,
    size_t    buf_size
) {
    // 1) 最小长度检查
    if (buf_size < MIN_PACKET_LEN) {
        return -1;
    }

    size_t index = 0;

    // 2) 协议头检查
    if (buf[index++] != 0xFF || buf[index++] != 0xFF) {
        return -2;
    }

    // 3) 读消息类型（大端）
    *msgType = (uint16_t)(buf[index] << 8) | buf[index + 1];
    index += 2;

    // 4) 读 dataLen（大端）
    *dataLen = (uint16_t)(buf[index] << 8) | buf[index + 1];
    index += 2;

    // 5) 检查剩余长度是否足够 data + 校验码
    if (index + *dataLen + 2 > buf_size) {
        return -3;
    }

    // 6) 拷贝 data
    memcpy(data, buf + index, *dataLen);
    index += *dataLen;

    // 7) 计算校验码
    uint16_t checkcode = 0;
    for (uint16_t i = 0; i < *dataLen; ++i) {
        checkcode += data[i];
    }

    // 8) 读取并校验
    uint16_t recv_check = (uint16_t)(buf[index] << 8) | buf[index + 1];
    if (recv_check != checkcode) {
        return -4;
    }
    index += 2;

    // 9) 返回实际解析的字节数
    return (int)index;
}


// int main(void) {
//     // 1) 准备输入参数
//     uint16_t msgType   = 0x0001;
//     uint8_t  data[5]   = {0x01, 0x02, 0x03, 0x04, 0x05};
//     uint16_t dataLen   = sizeof(data);        // 5
//     uint8_t  buf[4096];                         // 足够大的缓冲区
//     size_t   buf_size  = sizeof(buf);

//     // 2) 构造包
//     int packetLen = build_packet(msgType, data, dataLen, buf, buf_size);
//     if (packetLen < 0) {
//         printf("Error: build_packet failed (code %d)\n", packetLen);
//         return -1;
//     }

//     // 3) 打印构造好的原始包
//     printf("Packet built (%d bytes):\n", packetLen);
//     for (int i = 0; i < packetLen; i++) {
//         printf("%02X ", buf[i]);
//     }
//     printf("\n\n");

//     // 4) 解析包
//     uint16_t recvType;
//     uint8_t  recvData[4096];
//     uint16_t recvLen;
//     int ret = parse_packet(&recvType, recvData, &recvLen, buf, packetLen);
//     if (ret <= 0) {
//         printf("Error: parse_packet failed (code %d)\n", ret);
//         return -1;
//     }

//     // 5) 打印解析结果
//     printf("Parse succeeded!\n");
//     printf("Message Type: 0x%04X\n", recvType);
//     printf("Data Length : %u\n", recvLen);
//     printf("Data: ");
//     for (int i = 0; i < recvLen; i++) {
//         printf("%02X ", recvData[i]);
//     }
//     printf("\n");
//     printf("Frame Length: %d bytes\n", ret);

//     return 0;
// }